import threading,os.path,subprocess,sys
import tkinter as tk
from tkinter import ttk
from datetime import datetime

def resource_path(relative_path):
    if getattr(sys, 'frozen', False): #是否Bundle Resource
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

ico_path = resource_path(os.path.join("ui", "svn-logo.ico"))

class SVNUpdaterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("SVN更新 v1.0.0")
        self.root.geometry("720x310")
        self.root.resizable(False, False)

        # 路径输入框
        self.path_label = ttk.Label(root, text="SVN 路径")
        self.path_label.grid(row=0, column=0, padx=0, pady=10)
        self.path_entry_var = tk.StringVar()
        self.path_entry = ttk.Entry(self.root, textvariable=self.path_entry_var, width=65)
        self.path_entry.grid(row=0, column=1, padx=0, pady=10)

        # 更新按钮
        self.update_button = ttk.Button(self.root, text="更新", command=self.start_update_thread)
        self.update_button.grid(row=0, column=2, padx=0, pady=10)

        # 信息显示框
        self.info_text = tk.Text(self.root, wrap="word", height=15, width=95)
        self.info_text.grid(row=1, column=0, columnspan=3, padx=10, pady=10)
        self.info_text_scrollbar = ttk.Scrollbar(self.root, orient="vertical", command=self.info_text.yview)
        self.info_text_scrollbar.grid(row=1, column=3, sticky="ns")
        self.info_text.config(yscrollcommand=self.info_text_scrollbar.set)

        # 时间钟
        self.clock_label_var = tk.StringVar()
        self.clock_label = ttk.Label(self.root, textvariable=self.clock_label_var, font=("Helvetica", 12))
        self.clock_label.grid(row=2, column=0, columnspan=4, padx=10, pady=10, sticky="se")

        # 初始化时钟
        self.update_clock()

    def start_update_thread(self):
        self.update_button.configure(state="disabled")
        # 创建线程用于执行更新
        threading.Thread(target=self.update_svn, daemon=True).start()

    def update_svn(self):
        directory = self.path_entry_var.get()
        self.info_text.delete(1.0, tk.END)
        self.log_info("开始SVN更新...")
        while True:
            # 使用 Popen 启动子进程，通过迭代子进程的 stdout 来实时获取输出
            try:
                process = subprocess.Popen(["svn", "update", directory], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, creationflags=subprocess.CREATE_NEW_CONSOLE, shell=True)

            except:
                self.log_info("SVN启动失败\n")
                break
            process_info = []
            for line in process.stdout:
                process_info.append(line.strip())
                for i in process_info:
                    if "At revision" in i:
                        process_info = ["At revision"]
                        break
                    else:
                        process_info = []
                self.log_info(line.strip())

            process.wait()

            self.log_info('请求返回码：' + str(process.returncode))

            if process.returncode == 0:
                self.log_info("SVN更新完成!")
                self.update_button.configure(state="normal")
                break

            elif process.returncode != 0 and "cleanup" in process.stderr.read():
                self.log_info("SVN更新错误，正在运行cleanup清理...")
                c_run = subprocess.run(["svn", "cleanup", directory], capture_output=True, text=True, check=False, creationflags=subprocess.CREATE_NEW_CONSOLE, shell=True)
                if "database is locked" in c_run.stderr:
                    self.log_info("数据库已锁定\n 按以下方法解决：\n1、关闭程序，等一会再试。")
                    self.update_button.configure(state="normal")
                    break
                else:
                    self.log_info("重启SVN更新...")

            elif process.returncode == 1:
                if process_info:
                    for i in process_info:
                        if "At revision" in i:
                            c_process = subprocess.Popen(["svn", "update", directory], stdout=subprocess.PIPE,stderr=subprocess.PIPE, text=True, bufsize=1,creationflags=subprocess.CREATE_NEW_CONSOLE, shell=True)
                            c_process.wait()
                            self.info_text.delete("1.0", tk.END)
                            self.log_info('请求返回码：' + str(c_process.returncode))
                            self.log_info("部分内容更新失败,详细内容如下：")
                            for line in c_process.stdout:
                                self.log_info(line.strip())
                            for line in c_process.stderr:
                                self.log_info(line.strip())
                            self.log_info('错误内容的解释自行查看SVN相关文档！')
                            self.log_info('SVN更新完成!')
                            self.update_button.configure(state="normal")
                    break
                self.log_info("重启SVN更新...")

    def log_info(self, message):
        timestamp = datetime.now().strftime("%H:%M:%S")
        log_message = f"[{timestamp}] {message}\n"
        self.info_text.insert(tk.END, log_message)
        self.info_text.see(tk.END)  # 滚动到最后一行

    def update_clock(self):
        current_time = datetime.now().strftime("%H:%M:%S")
        self.clock_label_var.set(current_time)
        self.root.after(1000, self.update_clock)  # 每秒更新一次时钟

if __name__ == "__main__":
    root = tk.Tk()
    root.iconbitmap(default= ico_path)
    app = SVNUpdaterApp(root)
    root.mainloop()